#pragma once

#include <windows.h>
#include "../SAGAMath/zfx3d.h"

// everything went smooth
#define SAGA_OK                        	S_OK
// just reports no errors
#define SAGA_CANCELED                  	0x02000001
// general error message
#define SAGA_FAIL                      	0x82000001
// specific error messages
#define SAGA_CREATEAPI                 	0x82000002
#define SAGA_CREATEDEVICE              	0x82000003
#define SAGA_CREATEBUFFER              	0x82000004
#define SAGA_INVALIDPARAM              	0x82000005
#define SAGA_INVALIDID                 	0x82000006
#define SAGA_BUFFERSIZE                	0x82000007
#define SAGA_BUFFERLOCK                	0x82000008
#define SAGA_NOTCOMPATIBLE             	0x82000009
#define SAGA_OUTOFMEMORY               	0x8200000a
#define SAGA_FILENOTFOUND              	0x8200000b
#define SAGA_INVALIDFILE               	0x8200000c
#define SAGA_NOSHADERSUPPORT           	0x8200000d
#define SAGA_FAILa              	 	0x8200000c
#define SAGA_FAILb              	 	0x8200000d
#define SAGA_FAILc              	 	0x8200000e
#define SAGA_FAILd              	 	0x8200000f

////////////////////////////////////////
//	Vertex Types
typedef struct PVERTEX_TYPE {
	float	 x, y, z;
} PVERTEX;

typedef struct VERTEX_TYPE {
	float	 x, y, z;
	float  vcN[3];
	float  tu, tv;
} VERTEX;

typedef struct LVERTEX_TYPE {
	float	 x, y, z;
	DWORD  Color;
	float  tu, tv;
} LVERTEX;

typedef struct CVERTEX_TYPE {
	float	 x, y, z;
	float  vcN[3];
	float  tu, tv;
	float  fBone1, fWeight1; 
	float  fBone2, fWeight2;
} CVERTEX;

typedef struct VERTEX3T_TYPE {
	float	 x, y, z;
	float  vcN[3];
	float  tu0, tv0;
	float  tu1, tv1;
	float  tu2, tv2;
} VERTEX3T;

typedef struct TVERTEX_TYPE {
	float	 x, y, z;
	float  vcN[3];
	float  tu, tv;
	float  vcU[3];
} TVERTEX;
//
////////////////////////////////////////

////////////////////////////////////////
//	Enum Name: SAGAVERTEXID
typedef enum SAGAVERTEXID_TYPE 
{
	VID_PS,       // untransformed position only
	VID_UU,       // untransformed and unlit vertex
	VID_UL,       // untransformed and lit vertex vertex
	VID_CA,       // used for character animation
	VID_3T,       // three texture coord pairs
	VID_TV        // like UU but with tangent vector
} SAGAVERTEXID;
//
////////////////////////////////////////

////////////////////////////////////////
//	Enum Name: SAGAENGINEMODE
typedef enum SAGAENGINEMODE_TYPE 
{
	EMD_PERSPECTIVE,      // perspective projection
	EMD_TWOD,             // world coords equal to screen coords
	EMD_ORTHOGONAL        // orthogonal projection
} SAGAENGINEMODE;
//
////////////////////////////////////////

////////////////////////////////////////
//	Enum Name: SAGALIGHTID
typedef enum SAGALIGHTID_TYPE 
{
	LGT_DIRECTIONAL,  // directional light source
	LGT_POINT,        // point light source
	LGT_SPOT          // spot light source
} SAGALIGHTID;
//
////////////////////////////////////////

////////////////////////////////////////
//	Enum Name: SGAINPUTDEV
typedef enum SAGAINPUTDEV_TYPE 
{
	IDV_KEYBOARD,
	IDV_JOYSTICK,
	IDV_MOUSE
} SAGAINPUTDEV;
//
////////////////////////////////////////

////////////////////////////////////////
//	Enum Name: SAGADATATYPE
typedef enum SAGADATATYPE_TYPE 
{
	DAT_BOOL,          // boolean
	DAT_INT,           // integer
	DAT_FLOAT          // floating point
} SAGADATATYPE;
//
////////////////////////////////////////

////////////////////////////////////////
//	Enum Name: SAGASHADER
typedef enum SAGASHADER_TYPE 
{
	SHT_VERTEX,
	SHT_PIXEL
} SAGASHADERTYPE;
//
////////////////////////////////////////

////////////////////////////////////////
//	Enum Name: SAGANETMODE
typedef enum SAGANETMODE_TYPE 
{
	NMD_SERVER=0,
	NMD_CLIENT=1,
} SAGANETMODE;
//
////////////////////////////////////////

////////////////////////////////////////
//	Enum Name: SAGARENDERSTATE
typedef enum SAGARENDERSTATE_TYPE 
{
	RS_NONE,             // just nothing
	RS_CULL_CW,          // cull clockwise ordered triangles
	RS_CULL_CCW,         // cull counter cw ordered triangles
	RS_CULL_NONE,        // render front- and backsides
	RS_DEPTH_READWRITE,  // read and write depth buffer
	RS_DEPTH_READONLY,   // read but don't write depth buffer
	RS_DEPTH_NONE,       // no read or write with depth buffer
	RS_SHADE_POINTS,     // render just vertices
	RS_SHADE_LINES,      // render two verts as one line
	RS_SHADE_TRIWIRE,    // render triangulated wire
	RS_SHADE_HULLWIRE,   // render poly hull as polyline
	RS_SHADE_SOLID,      // render solid polygons
	RS_TEX_ADDSIGNED,    // texture stage operation
	RS_TEX_MODULATE,     // texture stage operation
	RS_STENCIL_DISABLE,        // stencilbuffer off
	RS_STENCIL_ENABLE,         // stencilbuffer off
	RS_STENCIL_FUNC_ALWAYS,    // stencil pass mode
	RS_STENCIL_FUNC_LESSEQUAL, // stencil pass mode
	RS_STENCIL_MASK,           // stencil mask
	RS_STENCIL_WRITEMASK,      // stencil write mask
	RS_STENCIL_REF,            // reference value
	RS_STENCIL_FAIL_DECR,      // stencil fail decrements
	RS_STENCIL_FAIL_INCR,      // stencil fail increments
	RS_STENCIL_FAIL_KEEP,      // stencil fail keeps
	RS_STENCIL_ZFAIL_DECR,     // stencil pass but z fail decrements
	RS_STENCIL_ZFAIL_INCR,     // stencil pass but z fail increments
	RS_STENCIL_ZFAIL_KEEP,     // stencil pass but z fail keeps
	RS_STENCIL_PASS_DECR,      // stencil and z pass decrements
	RS_STENCIL_PASS_INCR,      // stencil and z pass increments
	RS_STENCIL_PASS_KEEP,      // stencil and z pass keeps
	RS_DEPTHBIAS               // bis value to add to depth value
} SAGARENDERSTATE;
//
////////////////////////////////////////


////////////////////////////////////////
//	Struct Name: SAGAVIEWPORT
typedef struct SAGAVIEWPORT_TYPE 
{
	DWORD X;    // position of upper
	DWORD Y;    // ... left corner
	DWORD Width;
	DWORD Height;
} SAGAVIEWPORT;
//
////////////////////////////////////////

////////////////////////////////////////
//	Struct Name: SAGACOLOR
typedef struct SAGACOLOR_TYPE
{
	union
	{
		struct 
		{
			float fR;
			float fG;
			float fB;
			float fA;
		};
		float c[4];
	};
}SAGACOLOR;
//
////////////////////////////////////////

////////////////////////////////////////
//	Struct Name: SAGAMATERIAL
typedef struct SAGAMATERIAL_TYPE
{
	SAGACOLOR	cDiffuse;
	SAGACOLOR	cAmbient;
	SAGACOLOR	cSpecular;
	SAGACOLOR	cEmissive;
	float		fPower;
}SAGAMATERIAL;
//
////////////////////////////////////////

////////////////////////////////////////
//	Struct Name: SAGATEXTURE
typedef struct SAGATEXTURE_TYPE
{
	float		fAlpha;		//	Overall Transparency value
	char		*chName;	//	Texture FileName
	void		*pData;		//	Texture data
	SAGACOLOR	*pClrKeys;	//	color key array
	DWORD		dwNum;		//	Number of color keys
}SAGATEXTURE;
//
////////////////////////////////////////

////////////////////////////////////////
//	Struct Name: SAGASKIN
typedef struct SAGASKIN_TYPE
{
	bool	bAlpha;
	UINT	nMaterial;
	UINT	nTexture[8];
}SAGASKIN;
//
////////////////////////////////////////

////////////////////////////////////////
//	Stuct Name: SAGALIGHT
typedef struct SAGALIGHT_TYPE 
{
	SAGALIGHTID Type;           // type of light
	SAGACOLOR   cDiffuse;       // RGBA diffuse light value
	SAGACOLOR   cSpecular;      // RGBA specular light value
	SAGACOLOR   cAmbient;       // RGBA ambient light value
	SAGAVector  vcPosition;     // light position
	SAGAVector  vcDirection;    // light direction
	float      fRange;         // range of light
	float      fTheta;         // angle of spot light inner cone
	float      fPhi;           // angle of spot light outer cone
	float      fAttenuation0;  // change of intensity over distance
	float      fAttenuation1;  // change of intensity over distance
} SAGALIGHT;
//
////////////////////////////////////////